Function.RegisterNamespace("Test.System.IO");

[Fixture]
Test.System.IO.File=function(){
    [Fixture]
    function File(){
        [Fact]
        function InitializesStrategyManager(){
            var expected=System.Script.Strategy.StrategyManager;
        
            var actual=System.IO.File.Strategies;
            
            Assert.True(Object.IsType(expected,actual));
        }
    }

    [Fixture]
    function DeleteFile(){
        [Fact]
        function ThrowsIfPathIsOmitted(){
            var expected="System.IO.File.DeleteFile: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.File.DeleteFile();
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfPathIsUndefined(){
            var expected="System.IO.File.DeleteFile: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.File.DeleteFile(undefined);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfPathIsNull(){
            var expected="System.IO.File.DeleteFile: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.File.DeleteFile(null);
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfPathIsNotConvertibleToString(){
            var expected="System.IO.File.DeleteFile: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.File.DeleteFile({toString:null});
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function CallsToStringMethodOnPath(){
            var target={toString:function(){
                actual=true;
                return "";
            }};
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {
                    Exists:function(){
                        return true;
                    },
                    DeleteFile:function(){
                        return null;
                    }
                };
            };
            var actual=false;
            
            System.IO.File.DeleteFile(target);
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function GetsStrategyFromStrategyManager(){
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                actual=true;
                return {
                    Exists:function(){
                        return true;
                    },
                    DeleteFile:function(){
                        return null;
                    }
                };
            };
            var actual=false;

            System.IO.File.DeleteFile("");
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function CallsDeleteFileMethodOnStrategy(){
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {
                    Exists:function(){
                        return true;
                    },
                    DeleteFile:function(){
                        actual=true;
                }};
            };
            var actual=false;
            
            System.IO.File.DeleteFile("");
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function ReturnsValueOfDeleteFileMethodFromStrategy(){
            var expected="expected";
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {
                    Exists:function(){
                        return true;
                    },
                    DeleteFile:function(){
                        return expected;
                }}
            };
            
            var actual=System.IO.File.DeleteFile("");
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfStrategyManagerGetMethodThrows(){
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                throw new Error();
            };

            var actual=Record.Exception(function(){
                System.IO.File.DeleteFile("");
            });            
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.NotNull(actual);
        }

        [Fact]
        function ThrowsWhatStrategyManagerGetMethodThrows(){
            var target="expected";
            var expected=String.Format("System.IO.File.DeleteFile: {0}",target);
            var targetGet=System.IO.File.Strategies.Get;
            var calls=0;
            System.IO.File.Strategies.Get=function(){
                if(++calls==2)throw new Error(target);
                return {
                    DeleteFile:function(){},
                    Exists:function(){
                        return true;
                    }
                };
            };

            var actual=Record.Exception(function(){
                System.IO.File.DeleteFile("");
            });
            System.IO.File.Strategies.Get=targetGet;

            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfDeleteFileMethodThrows(){
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {
                    Exists:function(){
                        return true;
                    },
                    DeleteFile:function(){
                        throw new Error();
                }}
            };

            var actual=Record.Exception(function(){
                System.IO.File.DeleteFile("");
            });
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.NotNull(actual);
        }

        [Fact]
        function ThrowsWhatStrategyDeleteFileMethodThrows(){
            var target="expected";
            var expected=String.Format("System.IO.File.DeleteFile: {0}",target);
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {
                    Exists:function(){
                        return true;
                    },
                    DeleteFile:function(){
                        throw new Error(target);
                    }
                }
            };

            var actual=Record.Exception(function(){
                System.IO.File.DeleteFile("");
            });
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ReturnsUndefinedIfFileExistsMethodReturnsFalse(){
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {Exists:function(){
                    return false;
                }}
            };

            var actual=System.IO.File.DeleteFile("");
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.Undefined(actual);
        }
    }

    [Fixture]
    function Exists(){
        [Fact]
        function ThrowsIfPathIsOmitted(){
            var expected="System.IO.File.Exists: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.File.Exists();
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfPathIsUndefined(){
            var expected="System.IO.File.Exists: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.File.Exists(undefined);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfPathIsNull(){
            var expected="System.IO.File.Exists: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.File.Exists(null);
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfPathIsNotConvertibleToString(){
            var expected="System.IO.File.Exists: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.File.Exists({toString:null});
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function CallsToStringMethodOnPath(){
            var target={toString:function(){
                actual=true;
                return '';
            }};
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {Exists:function(){}}
            };
            var actual=false;
            
            System.IO.File.Exists(target);
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function GetsStrategyFromStrategyManager(){
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                actual=true;
                return {Exists:function(){}}
            };
            var actual=false;
            
            System.IO.File.Exists("");
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function CallsExistsMethodOnStrategy(){
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {Exists:function(){
                    actual=true;
                }}
            };
            var actual=false;
            
            System.IO.File.Exists("");
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function ReturnsValueOfExistsMethodFromStrategy(){
            var expected="expected";
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {Exists:function(){
                    return expected;
                }}
            };
            
            var actual=System.IO.File.Exists("");
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfStrategyManagerGetMethodThrows(){
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                throw new Error();
            };

            var actual=Record.Exception(function(){
                System.IO.File.Exists("");
            });            
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.NotNull(actual);
        }

        [Fact]
        function ThrowsWhatStrategyManagerGetMethodThrows(){
            var target="expected";
            var expected=String.Format("System.IO.File.Exists: {0}",target);
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                throw new Error(target);
            };

            var actual=Record.Exception(function(){
                System.IO.File.Exists("");
            });
            System.IO.File.Strategies.Get=targetGet;

            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfExistsMethodThrows(){
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {Exists:function(){
                    throw new Error();
                }}
            };

            var actual=Record.Exception(function(){
                System.IO.File.Exists("");
            });
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.NotNull(actual);
        }

        [Fact]
        function ThrowsWhatStrategyExistsMethodThrows(){
            var target="expected";
            var expected=String.Format("System.IO.File.Exists: {0}",target);
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                throw new Error(target);
            };

            var actual=Record.Exception(function(){
                System.IO.File.Exists("");
            });
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.Equal(expected,actual);
        }
    }

    [Fixture]
    function GetFile(){
        [Fact]
        function ThrowsIfPathIsOmitted(){
            var expected="System.IO.File.GetFile: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.File.GetFile();
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfPathIsUndefined(){
            var expected="System.IO.File.GetFile: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.File.GetFile(undefined);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfPathIsNull(){
            var expected="System.IO.File.GetFile: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.File.GetFile(null);
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfPathIsNotConvertibleToString(){
            var expected="System.IO.File.GetFile: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.File.GetFile({toString:null});
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function CallsToStringMethodOnPath(){
            var target={toString:function(){
                actual=true;
                return "";
            }};
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {Exists:function(){},GetFile:function(){}}
            };
            var actual=false;
            
            System.IO.File.GetFile(target);
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function GetsStrategyFromStrategyManager(){
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                actual=true;
                return {
                    Exists:function(){
                        return true;
                    },
                    GetFile:function(){
                        return null;
                    }
                };
            };
            var actual=false;

            System.IO.File.GetFile("");
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function CallsGetFileMethodOnStrategy(){
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {
                    Exists:function(){
                        return true;
                    },
                    GetFile:function(){
                        actual=true;
                }};
            };
            var actual=false;
            
            System.IO.File.GetFile("");
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function ReturnsValueOfGetFileMethodFromStrategy(){
            var expected="expected";
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {
                    Exists:function(){
                        return true;
                    },
                    GetFile:function(){
                        return expected;
                }}
            };
            
            var actual=System.IO.File.GetFile("");
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfStrategyManagerGetMethodThrows(){
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                throw new Error();
            };

            var actual=Record.Exception(function(){
                System.IO.File.GetFile("");
            });            
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.NotNull(actual);
        }

        [Fact]
        function ThrowsWhatStrategyManagerGetMethodThrows(){
            var target="expected";
            var expected=String.Format("System.IO.File.GetFile: {0}",target);
            var targetGet=System.IO.File.Strategies.Get;
            var calls=0;
            System.IO.File.Strategies.Get=function(){
                throw new Error(target);
            };

            var actual=Record.Exception(function(){
                System.IO.File.GetFile("");
            });
            System.IO.File.Strategies.Get=targetGet;

            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfGetFileMethodThrows(){
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {
                    Exists:function(){
                        return true;
                    },
                    GetFile:function(){
                        throw new Error();
                }}
            };

            var actual=Record.Exception(function(){
                System.IO.File.GetFile("");
            });
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.NotNull(actual);
        }

        [Fact]
        function ThrowsWhatStrategyGetFileMethodThrows(){
            var target="expected";
            var expected=String.Format("System.IO.File.GetFile: {0}",target);
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {
                    Exists:function(){
                        return true;
                    },
                    GetFile:function(){
                        throw new Error(target);
                    }
                }
            };

            var actual=Record.Exception(function(){
                System.IO.File.GetFile("");
            });
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.Equal(expected,actual);
        }
    }
    
    [Fixture]
    function SaveFile(){
        [Fact]
        function ThrowsIfPathIsOmitted(){
            var expected="System.IO.File.SaveFile: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.File.SaveFile();
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfPathIsUndefined(){
            var expected="System.IO.File.SaveFile: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.File.SaveFile(undefined);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfPathIsNull(){
            var expected="System.IO.File.SaveFile: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.File.SaveFile(null);
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfPathIsNotConvertibleToString(){
            var expected="System.IO.File.SaveFile: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.File.SaveFile({toString:null});
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function CallsToStringMethodOnPath(){
            var target={toString:function(){
                actual=true;
                return "";
            }};
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {
                    Exists:function(){
                        return true;
                    },
                    SaveFile:function(){
                    }
                };
            };
            var actual=false;
            
            System.IO.File.SaveFile(target);
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function GetsStrategyFromStrategyManager(){
            var targetGet=System.IO.File.Strategies.Get;
            var calls=0;
            System.IO.File.Strategies.Get=function(){
                actual=true;
                return {
                    Exists:function(){
                        return true;
                    },
                    SaveFile:function(){
                    }
                };
            };
            var actual=false;

            System.IO.File.SaveFile('');
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function CallsSaveFileMethodOnStrategy(){
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {
                    Exists:function(){
                        return true;
                    },
                    SaveFile:function(){
                        actual=true;
                }};
            };
            var actual=false;
            
            System.IO.File.SaveFile('');
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function ReturnsTrueIfSaveFileDoesNotThrow(){
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {
                    Exists:function(){
                        return true;
                    },
                    SaveFile:function(){
                        return true;
                    }
                };
            };
            var actual=System.IO.File.SaveFile('');
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function ReturnsFalseIfSaveFileThrows(){
            var targetGet=System.IO.File.Strategies.Get;
            System.IO.File.Strategies.Get=function(){
                return {
                    Exists:function(){
                        return true;
                    },
                    SaveFile:function(){
                        throw new Error();
                    }
                };
            };
            var actual=System.IO.File.SaveFile('');
            System.IO.File.Strategies.Get=targetGet;
            
            Assert.False(actual);
        }
    }
}